/*
 * Main.java
 *
 * Created on 20 marzec 2007, 21:11
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package server;

import data.*;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
import java.util.*;
import org.hibernate.Hibernate;
import util.HibernateUtil;
import org.hibernate.Session;

/**
 *
 * @author xavex
 */
public class Main extends UnicastRemoteObject implements VacationServer {
    
    
    
    public Main() throws RemoteException {

    }
    
    public static void main(String args[])
    {
        try
        {
            System.setSecurityManager(new RMISecurityManager());
            //set the security manager

            //create a local instance of the object
            Main server = new Main();

            //put the local instance in the registry
            Naming.rebind(Constants.SERVER , server);

            System.out.println("Server waiting.....");
        }
        catch (java.net.MalformedURLException me) {
            System.out.println("Malformed URL: " + me.toString());   
        }
        catch (RemoteException re) {
            System.out.println("Remote exception: " + re.toString());  
        }
  }

    public String getHelloWorld()  throws RemoteException {
        return "Hello, world!";
    }

    public Set<Team> getTeams() throws RemoteException {
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        
        Set<Team> teams = new HashSet<Team>();
        
        teams.addAll( session.createQuery( "FROM Team" ).list() );
        
        session.getTransaction().commit();
        return teams;
    }

    public Team saveTeam(Team team) throws RemoteException {
        return (Team)saveObject( team );
    }
    
    public Set<Team> saveTeams( Set<Team> teams ) throws RemoteException  {
        return saveObjects( teams );
    }
    
    
    public Team reloadTeam( Team team, boolean withMembers, boolean withQuotas ) throws RemoteException {
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();

        Team newTeam = (Team)session.get( Team.class, team.getId() );
        
        if( withMembers )
            newTeam.getMembers().size();
        
        if( withQuotas )
            newTeam.getQuotas().size();
        
        session.getTransaction().commit();        
        
        return newTeam;
    }

    public Employee saveEmployee(Employee emp) throws RemoteException {
        return (Employee)saveObject(emp);
    }

    /**
     * @param o
     */
    private IDbObject saveObject(IDbObject o) {
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        
        //session.saveOrUpdate( o );        
        session.merge( o );
                
        session.getTransaction().commit();
        
        return o;
    }

    public Set<Employee> saveEmployees(Set<Employee> emps) throws RemoteException {
        return (Set<Employee>)saveObjects( emps );
    }
    
    public Set saveObjects( Set objs ) {
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();

        for( Object o : objs ) {
            session.merge( o );
        }
        
        session.getTransaction().commit();
        
        return objs; 
    }

    public Employee reloadEmployeeWithVacations(Employee emp) throws RemoteException {
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();

        emp = reloadEmp( session, emp );
        
        session.getTransaction().commit();
        
        return emp;
    }

    public Set<Employee> reloadEmployeesWithVacations(Set<Employee> emps) throws RemoteException {
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        
        Set<Employee> newEmps = new HashSet<Employee>();
        
        for( Employee e : emps ) {                                   
            newEmps.add( reloadEmp(session, e) );
        }
        
        session.getTransaction().commit();
        
        return newEmps;
    }

    /**
     * @param session
     * @param e
     */
    private Employee reloadEmp(final Session session, final Employee e) {
        Employee newEmp = (Employee) session.get( Employee.class, e.getId() );
        newEmp.getVacations().size();
        return newEmp;
    }

    public void delete(Object o) throws RemoteException {
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        
        session.delete( o );
        
        session.getTransaction().commit();
        
    }

    public VacQuota saveQuota(VacQuota quota) throws RemoteException {
        return (VacQuota) saveObject( quota );
    }

    public Set<VacQuota> saveQuotas(Set<VacQuota> quotas) throws RemoteException {
        return (Set<VacQuota>)saveObjects( quotas );
    }

    public Vacation getVacation( int year, int month, int day ) throws RemoteException {
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        
        Calendar c = Calendar.getInstance();
        c.clear();
        c.set( year, month, day );
        
        Date date = c.getTime();
        
        List<Vacation> vacs = session.createQuery( "from Vacation vac where vacationDate = ?").setDate( 0, date ).list();
        Vacation vac = null;
        
        if( vacs.size() == 0 ) {
            vac = new Vacation();
            vac.setVacationDate( date );
            session.save( vac );
        }   
        else {
            vac = vacs.get( 0 );
        }
                    
        session.getTransaction().commit();
        return vac;
    }

    public Vacation reloadVacationWithEmployees(Vacation vac) throws RemoteException {
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        
        Vacation newVac = (Vacation) session.get( Vacation.class, vac.getId() );
        newVac.getEmployees().size();
        
        session.getTransaction().commit();
        return newVac;        
    }

    public Vacation saveVacation(Vacation vac) throws RemoteException {
        return (Vacation)saveObject( vac );
    }

    public Set<Employee> getEmployees() throws RemoteException {
        Set<Employee> emps = new HashSet<Employee>();
        
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        
        List<Team> teams = session.createQuery( "FROM Team" ).list();
        
        for( Team team : teams )
            emps.addAll( team.getMembers() );
        
//        for( Employee emp : emps )
//            emp.getTeam().getName();
        
        session.getTransaction().commit();
        return emps;
    }
}
